<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/1/10
 * Time: 9:17
 */
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use App\Models\MessagesSent;
use App\Models\MessagesSentSucceed;
use App\Models\User;
use App\Models\AddressBookBinding;
use Illuminate\Support\Facades\Schema;
use App\Jobs\SnsQueue;

class send_group_sms extends Command{
    /**
     * @var 设置执行的命令
     */
    protected $signature  = 'send_group_sms:send {action}';

    protected $send_group_sms_key;
    protected $msg_id;
    protected $send_success_group_sms_key;

    /**
     * The console command description.
     *
     * @var string
     */

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // 获取参数，调用方法
        $action = $this->argument('action');
        $this->$action();
    }

    /**
     * @desc 生成群发短信队列
     */
    public function generate_group_sms_queue()
    {
        $msg_id = Redis::lpop("SentGroupMessages_data");
        if(empty($msg_id)) {
            return true;
        }
        $messages_info = MessagesSent::where(['id' => $msg_id])->first();
        if(empty($messages_info)) {
            return ['status'=>'error', 'message'=>'群发短信未找到'];
        }
        if($messages_info->status != 1) {
            return true; // 该队列已处理完
        }
        $this->msg_id = $msg_id;
        $this->send_group_sms_key = 'GroupSms:send_group_sms_mobile_'.$msg_id;  // 待发送的手机缓存KEY
        $this->send_success_group_sms_key = 'GroupSms:send_group_sms_mobile_success_'.$this->msg_id;    // 已发送的手机缓存KEY
        $this->set_send_success_cache();    // 已发送成功的写入缓存
        $this->_mobile_list($messages_info->user_type);
        $data = ['action'=>'group_sms_send', 'data'=>['msg_id'=>$msg_id, 'msg_type'=> 0, 'content'=> $messages_info->content]];
        dispatch((new SnsQueue($data))->onQueue('sns_queue'));
        redis::del($this->send_success_group_sms_key);  // 删除已发送的缓存

        return true;
    }

    protected function _mobile_list($user_type){
        $user_fields = ['mobile'];
        $address_book_fields = ['addrss_book_mobile'];
        switch($user_type) {
            case 0: // 全部用户
                // 用户表
                $this->_select_mobile('User', [['mobile', '!=', '']], $user_fields);
                // 通讯表
                $this->_select_mobile( 'AddressBookBinding', [['addrss_book_mobile', '!=' , '']], $address_book_fields);
                break;
            case 1: // 注册用户
                $this->_select_mobile( 'User', [['mobile', '!=', '']], $user_fields);
                break;
            case 2: // 通讯录用户
                $this->_select_mobile( 'AddressBookBinding', [['addrss_book_mobile', '!=' , '']], $address_book_fields);
                break;
            case 3: // 普通用户
                $this->_select_mobile( 'User', [['mobile', '!=', ''], ['role', '=', '0'], ['membership', '=', 0]], $user_fields);
                break;
            case 4: // 会员用户
                $this->_select_mobile( 'User', [['mobile', '!=', ''], ['membership', '=', 1]], $user_fields);
                break;
            case 5: // 股东用户
                $this->_select_mobile( 'User', [['mobile', '!=', ''], ['role', '=', '1']], $user_fields);
                break;
            default:
                break;
        }

        return true;
    }

    /**
     * @desc 获取需要发送的手机好保存到redis
     * @param $table_model
     * @param $where_arr
     * @param $fields
     * @return bool
     */
    protected function _select_mobile($table_model, $where_arr, $fields)
    {
        $page = 1;
        $batch_number = 100;
        if($table_model == "AddressBookBinding") {
            $total = AddressBookBinding::where($where_arr)->count();
        } else {
            $total = User::where($where_arr)->count();
        }

        $total_page = (int)ceil($total/$batch_number);
        for($i=0;$i<$total_page;$i++) {
            $offset = ($page - 1) * $batch_number;
            if($table_model == "AddressBookBinding") {
                $mobile_list = AddressBookBinding::where($where_arr)->skip($offset)->take($batch_number)->get($fields)->toArray();
            } else {
                $mobile_list = User::where($where_arr)->skip($offset)->take($batch_number)->get($fields)->toArray();
            }

            if(empty($mobile_list)) {
                break;
            }

            foreach($mobile_list as $mobile) {
                // 处理通讯录用户
                if($table_model == 'AddressBookBinding') {
                    if(empty($mobile['addrss_book_mobile'])) {
                        continue;
                    }
                    $mobile_arr = explode(',', $mobile['addrss_book_mobile']);

                    foreach($mobile_arr as $value) {
                        if(!$this->_checkout_send($value)) {
                            continue;
                        }
                        Redis::zadd($this->send_group_sms_key, [$value=>$value]);
                    }
                } else {
                    if(!$this->_checkout_send($mobile['mobile'])) {
                        continue;
                    }
                    Redis::zadd($this->send_group_sms_key, [$mobile['mobile'] => $mobile['mobile']]);
                }
            }

            ++$page;
        }

        return true;
    }

    /**
     * @desc 检测手机号是否已发送
     * @param $mobile 手机号
     * @return bool
     */
    protected function _checkout_send(&$mobile)
    {
        if(empty($mobile)) {
            return false;
        }
        $mobile = str_replace('+86', '', $mobile);
        // 检测手机的合法性
        if (!preg_match('/^(\+86(\-)?)?1[345789]\d{9}$/', str_replace(' ', '', $mobile))) {
            return false;
        }

        $is_record = Redis::zScore($this->send_success_group_sms_key, $mobile);
        if($is_record == $mobile) {
            return false;
        }
        return true;
    }

    /**
     * @desc 将已发送的手机号保存到Redis
     * @return bool
     */
    protected function set_send_success_cache()
    {
        $page = 1;
        $page_size = 1000;
        while (true) {
            $offset = ($page - 1) * $page_size;
            $mobile_list = MessagesSentSucceed::where(['msg_id' => $this->msg_id])->skip($offset)->take($page_size)->get()->toArray();
            if(empty($mobile_list)) {
                break;
            }

            foreach($mobile_list as $mobile) {
                Redis::zadd($this->send_success_group_sms_key, [$mobile['mobile'] =>$mobile['mobile']]);
            }
            ++$page;
        }

        return true;
    }
}